from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File
from sqlalchemy.ext.asyncio import AsyncSession
import os
import uuid
from datetime import datetime

from app.core.database import get_db
from app.core.deps import get_current_user, get_tenant_id
from app.core.security import verify_password, get_password_hash
from app.schemas.user import (
    ChangePasswordRequest, UpdateProfileRequest, ProfileResponse
)
from app.models.user import User
from app.services.user import user_service
from app.services.dept import dept_service
from app.services.role import role_service
from app.utils.response import ResponseUtil

router = APIRouter()


@router.get("/info", summary="获取个人信息", response_model=ProfileResponse)
async def get_profile(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
    tenant_id: str = Depends(get_tenant_id)
):
    """获取当前用户的个人信息"""
    try:
        # 获取用户详细信息
        user_detail = await user_service.get_user_detail(
            db=db, user_id=current_user.id, tenant_id=tenant_id
        )

        if not user_detail:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="用户信息不存在"
            )

        return ResponseUtil.success(data=user_detail)
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"获取个人信息失败: {str(e)}"
        )


@router.put("/info", summary="更新个人信息")
async def update_profile(
    profile_data: UpdateProfileRequest,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
    tenant_id: str = Depends(get_tenant_id)
):
    """更新个人信息"""
    try:
        # 检查邮箱唯一性（如果更新了邮箱）
        if profile_data.email and profile_data.email != current_user.email:
            existing_user = await user_service.get_by_email(
                db, email=profile_data.email, tenant_id=tenant_id
            )
            if existing_user and existing_user.id != current_user.id:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="邮箱已被其他用户使用"
                )

        # 更新用户信息
        update_data = profile_data.model_dump(exclude_unset=True)
        updated_user = await user_service.update_user(
            db=db,
            db_obj=current_user,
            obj_in=update_data
        )

        return ResponseUtil.success(data=updated_user, message="个人信息更新成功")
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"更新个人信息失败: {str(e)}"
        )


@router.put("/password", summary="修改密码")
async def change_password(
    password_data: ChangePasswordRequest,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """修改当前用户密码"""
    try:
        # 验证确认密码
        if password_data.new_password != password_data.confirm_password:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="新密码和确认密码不一致"
            )

        # 验证原密码
        if not verify_password(password_data.old_password, current_user.hashed_password):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="原密码错误"
            )

        # 检查新密码是否与原密码相同
        if password_data.old_password == password_data.new_password:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="新密码不能与原密码相同"
            )

        # 更新密码
        await user_service.update_password(
            db=db,
            user_id=current_user.id,
            password=password_data.new_password
        )

        return ResponseUtil.success(message="密码修改成功")
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"修改密码失败: {str(e)}"
        )


@router.post("/avatar", summary="上传头像")
async def upload_avatar(
    file: UploadFile = File(...),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """上传用户头像"""
    try:
        # 检查文件类型
        if not file.content_type or not file.content_type.startswith('image/'):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="只能上传图片文件"
            )

        # 检查文件大小（限制为5MB）
        file_size = 0
        content = await file.read()
        file_size = len(content)

        if file_size > 5 * 1024 * 1024:  # 5MB
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="文件大小不能超过5MB"
            )

        # 创建上传目录
        upload_dir = "static/avatars"
        os.makedirs(upload_dir, exist_ok=True)

        # 生成唯一文件名
        file_extension = os.path.splitext(file.filename)[1] if file.filename else '.jpg'
        unique_filename = f"{uuid.uuid4()}{file_extension}"
        file_path = os.path.join(upload_dir, unique_filename)

        # 保存文件
        with open(file_path, 'wb') as f:
            f.write(content)

        # 生成访问URL
        avatar_url = f"/static/avatars/{unique_filename}"

        # 更新用户头像
        await user_service.update_user(
            db=db,
            db_obj=current_user,
            obj_in={"avatar": avatar_url}
        )

        # 删除旧头像文件（如果存在且不是默认头像）
        if current_user.avatar and current_user.avatar.startswith('/static/avatars/'):
            old_file_path = current_user.avatar.lstrip('/')
            if os.path.exists(old_file_path):
                try:
                    os.remove(old_file_path)
                except Exception:
                    pass  # 忽略删除失败的情况

        return ResponseUtil.success(
            data={"avatar_url": avatar_url},
            message="头像上传成功"
        )
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"上传头像失败: {str(e)}"
        )


@router.get("/stats", summary="获取个人统计信息")
async def get_profile_stats(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
    tenant_id: str = Depends(get_tenant_id)
):
    """获取个人统计信息"""
    try:
        stats = {
            "user_id": current_user.id,
            "username": current_user.username,
            "login_count": 0,  # 可以从日志表获取
            "last_login_time": current_user.last_login_time,
            "last_login_ip": current_user.last_login_ip,
            "account_days": 0,  # 计算账户天数
            "tenant_id": tenant_id
        }

        # 计算账户天数
        if current_user.created_at:
            account_days = (datetime.now() - current_user.created_at).days
            stats["account_days"] = account_days

        return ResponseUtil.success(data=stats)
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"获取统计信息失败: {str(e)}"
        )


@router.get("/security", summary="获取安全信息")
async def get_security_info(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取账户安全信息"""
    try:
        # 计算密码强度（简单实现）
        password_strength = "中等"  # 这里可以基于实际的密码策略来计算

        # 计算密码使用天数
        password_days = 0
        if current_user.updated_at:
            password_days = (datetime.now() - current_user.updated_at).days

        security_info = {
            "password_strength": password_strength,
            "password_last_changed": current_user.updated_at.isoformat() if current_user.updated_at else None,
            "password_days": password_days,
            "two_factor_enabled": False,  # 假设暂时没有实现2FA
            "login_protection": True,
            "account_status": "正常" if current_user.status and current_user.is_active else "异常"
        }

        return ResponseUtil.success(data=security_info)
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"获取安全信息失败: {str(e)}"
        )